#include "FileHelper.h"
#include <QFile>
#include <QDir>
#include <QTextStream>
#include <QDateTime>

FileHelper::FileHelper(QObject* parent): QObject(parent)
{
}

QString FileHelper::lastError() const
{
    return m_lastError;
}

bool FileHelper::exists(const QString& path) const
{
    return QFileInfo::exists(path);
}

QString FileHelper::readText(const QString& path, const char* codecName)
{
    QFile file(path);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        setError(file.errorString());
        return "";
    }

    QTextStream in( & file);
    in.setCodec(codecName);
    QString content = in.readAll();
    file.close();
    return content;
}

bool FileHelper::writeText(const QString& path, const QString& content)
{
    QFile file(path);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        setError(file.errorString());
        return false;
    }

    QTextStream out( & file);
    out.setCodec("UTF-8");
    out << content;
    file.close();
    return true;
}

bool FileHelper::copy(const QString& src, const QString& dest)
{
    QFileInfo srcInfo(src);
    if (!srcInfo.exists())
    {
        setError("Source path not exists");
        return false;
    }

    if (srcInfo.isDir())
    {
        return copyRecursive(src, dest);
    }

    QFile srcFile(src);
    if (!srcFile.copy(dest))
    {
        setError(srcFile.errorString());
        return false;
    }
    return true;
}

bool FileHelper::remove(const QString& path)
{
    QFileInfo info(path);
    if (!info.exists()) return true;

    if (info.isDir())
    {
        QDir dir(path);
        if (!dir.removeRecursively())
        {
            setError("Failed to remove directory");
            return false;
        }
        return true;
    }

    QFile file(path);
    if (!file.remove())
    {
        setError(file.errorString());
        return false;
    }
    return true;
}

QVariantMap FileHelper::getInfo(const QString& path)
{
    QFileInfo info(path);
    return
    {
        {"absolutePath", info.absoluteFilePath()},
        {"fileName", info.fileName()},
        {"suffix", info.suffix()},
        {"size", info.size()},
        {"created", info.birthTime()},
        {"modified", info.lastModified()},
        {"isDir", info.isDir()}
    };
}

// 私有方法实现
void FileHelper::setError(const QString& error)
{
    m_lastError = error;
    emit errorOccurred(error);
}

bool FileHelper::copyRecursive(const QString& src, const QString& dest)
{
    QDir srcDir(src);
    if (!srcDir.exists())
    {
        setError("Source directory not exists");
        return false;
    }

    QDir destDir(dest);
    if (!destDir.mkpath("."))
    {
        setError("Cannot create destination directory");
        return false;
    }

    const auto files = srcDir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
    for (const auto & fileInfo : files)
    {
        QString srcPath = fileInfo.absoluteFilePath();
        QString destPath = dest + QDir::separator() + fileInfo.fileName();

        if (fileInfo.isDir())
        {
            if (!copyRecursive(srcPath, destPath))
            {
                return false;
            }
        }
        else
        {
            QFile file(srcPath);
            if (!file.copy(destPath))
            {
                setError(file.errorString());
                return false;
            }
        }
    }
    return true;
}
